/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package eu.ict_omelette.mashup.adapters.pipes.database.loader;

import com.sun.xml.internal.fastinfoset.util.StringArray;
import eu.ict_omelette.mashup.adapters.pipes.Canonical2Json;
import eu.ict_omelette.mashup.adapters.pipes.KindOfFile;
import eu.ict_omelette.mashup.canonicalmodel.CanonicalMashup;
import eu.ict_omelette.mashup.canonicalmodel.Component;
import eu.ict_omelette.mashup.canonicalmodel.Dataflow;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.net.URI;
import java.sql.*;
import java.util.ArrayList;
import java.util.Iterator;
/**
 *
 * @author guybrush
 */
public class TemplateKnowledgeLoader {

    static final String create = "create table if not exists Template " +
        "(componentName varchar(100), simple varchar(1024), list varchar(1024), cmplxList varchar(1024), listList varchar(1024)," +
        "dataMapped varchar(1024), UpVotes int(20), DownVotes int(20), Tags varchar(1024), primary key(componentName) ) ",
                        insert = "INSERT INTO Template (componentName, simple, list, cmplxList, listList, dataMapped) VALUES ",
                        present = "Select * From Template ",
                        mappedFieldsFileName = "mappedFields";
    private KindOfFile kof = null;

    public KindOfFile getKindOfFile() { return kof; }
    public void setKindOfFile(KindOfFile kof) { this.kof = kof; }

    public TemplateKnowledgeLoader(KindOfFile kof) { this.kof = kof; }

    public void LoadFolder(String path) throws SQLException
    {
        String[] children = new File(path).list();

        if(children == null || children.length < 1)
        { System.out.println("Directory does not exists or it is empty"); System.exit(1); }

        for(int i = 0; i < children.length; i++)
            LoadFile(path + "/" + children[i]);
    }
    public void LoadFile(URI uri) throws SQLException { LoadFile(uri.getPath()); }
    public void LoadFile(String filepath) throws SQLException
    {
        final String EMBED = "embed";
        File tmpFile = new File(filepath);
        //System.out.println(filepath);
        if (tmpFile.isFile())
        {
            Connection conn = null;
            Statement stat = null;

            try{
                Class.forName("org.sqlite.JDBC");
                conn = DriverManager.getConnection("jdbc:sqlite:bayatest.sqlite");
                stat = conn.createStatement();
                stat.execute(create);

                CanonicalMashup cm = new Canonical2Json(kof, filepath).getCanonicalMashup();

                for (Iterator<Component> it = cm.getComponents(); it.hasNext();) {
                    Component comp = it.next();
                    String comp_tp = comp.getType();

                    if (!comp_tp.toLowerCase().equals("output") && !isPresent(stat, comp_tp))
                    {
                        ArrayList<String> simple = new ArrayList<String>(); //[pair] = name of input; [odd] = value of input;
                        ArrayList<ArrayList<String>> cmplx_underscored = new ArrayList<ArrayList<String>>(); //[X,0] = name of list; [X,>0] = value of input;
                        ArrayList<ArrayList<String>> cmplx_pointed = new ArrayList<ArrayList<String>>(); //[X,0] = name of list; [X,odd index] = name of input; [X,pair index] = value of input;
                        ArrayList<ArrayList<ArrayList<String>>> cmplx_both = new ArrayList<ArrayList<ArrayList<String>>>(); //[0,0] = name of list; [>0,pair index] = name of input; [>0,odd index] = value of input;

                        Canonical2Json.getConfLists(comp.getInputParameters(), simple, cmplx_underscored, cmplx_pointed, cmplx_both);
                        if (comp.getIsEmbedding()) { simple.add(0, EMBED); simple.add(1, EMBED); }

                        String s_simple, s_cmplx_underscored, s_cmplx_pointed, s_cmplx_both;
                        s_simple = s_cmplx_underscored = s_cmplx_pointed = s_cmplx_both = "";
                        Integer sz = simple.size();
                        for(int x=0;x<sz;x=x+2)
                        {
                            if (!(simple.get(x).equals(EMBED) && simple.get(x + 1).equals(EMBED)))
                                 s_simple += simple.get(x) + getTypeFromInputValue(simple.get(x+1));
                            else s_simple += EMBED + ":" + EMBED;
                            
                            if (x < sz - 2) s_simple += ";";
                        }

                        sz = cmplx_underscored.size();
                        for(int x=0;x<sz;x++)
                        {
                            ArrayList<String> tmp = cmplx_underscored.get(x);
                            s_cmplx_underscored += tmp.get(0);

                            Integer sz2 = tmp.size();
                            if (sz2 > 1)
                                for(int y=1;y<sz2-1;y++) s_cmplx_underscored += getTypeFromInputValue(tmp.get(y));
                            s_cmplx_underscored += getTypeFromInputValue(tmp.get(sz2 - 1));

                            if (x < sz -1) s_cmplx_underscored += ";";
                        }

                        sz = cmplx_pointed.size(); 
                        for(int x=0;x<sz;x++)
                        {
                            ArrayList<String> tmp = cmplx_pointed.get(x);
                            s_cmplx_pointed += tmp.get(0) + "["; Integer sz2 = tmp.size();
                            for(int y=1;y<sz2-2;y=y+2) 
                                s_cmplx_pointed += tmp.get(y) + getTypeFromInputValue(tmp.get(y+1)) + ";";
                            s_cmplx_pointed += tmp.get(sz2-2) + getTypeFromInputValue(tmp.get(sz2-1)) + "]";
                            if (x < sz - 1) s_cmplx_pointed += ";";
                        }
                        sz = cmplx_both.size(); 
                        for(int x=0;x<sz;x++)
                        {
                            ArrayList<ArrayList<String>> tmp = cmplx_both.get(x); Integer sz2 = tmp.size();
                            String old_field = "", new_field = ""; Boolean need_comma = false;
                            s_cmplx_both += tmp.get(0).get(0) + "[";
                            for(int y=1;y<sz2;y++)
                            {
                                ArrayList<String> tmp2 = tmp.get(y); Integer sz3 = tmp2.size();
                                new_field = "{";
                                for(int z=0;z<sz3;z=z+2)
                                { new_field += tmp2.get(z) + getTypeFromInputValue(tmp2.get(z+1)) ; if (z < sz3 - 2) new_field += ";"; }
                                new_field += "}";
                                if (!new_field.equals(old_field)) 
                                { 
                                    if (need_comma) s_cmplx_both += ";";
                                    s_cmplx_both += new_field; old_field = new_field;
                                    need_comma = true;
                                }
                            }
                            s_cmplx_both += "]"; if (x < sz - 1) s_cmplx_both += ";";
                        }

                        addRow(stat, comp_tp, s_simple, s_cmplx_underscored, s_cmplx_pointed, s_cmplx_both);
                    }
                }
            }catch(Exception e){ e.printStackTrace(); }
            finally
            {
                if (stat != null) stat.close();
                if (conn != null) conn.close();
            }
        }
    }

    static private String getTypeFromInputValue(String str)
    {
        String tp;
        try {
            tp = str.split("\"type\":\"")[1].split("\"")[0];// try whit '"type":"'    //String tp = str.split(",")[1].split(":")[1].split("\"")[1].split("\"")[0];
        } catch (Exception ex) {
            tp = "";
        }

        //suggestion
            if (tp.isEmpty()) tp = "text";
        //
        return ":" + tp;
    }
    static private String getDefWhereStmt(String comp)
    { return " WHERE componentName = '" + comp + "'"; }
    static private void addRow(Statement stmt, String comp, String simple, String cmplx_underscored,
            String cmplx_pointed, String cmplx_both) throws SQLException, FileNotFoundException, IOException
    {
        String notMappedFields = "";
        File notMappedFieldsF = new File(mappedFieldsFileName);
        if (notMappedFieldsF.exists() && notMappedFieldsF.isFile())
        {
            String row = null; BufferedReader br = new BufferedReader(new FileReader(notMappedFieldsF));
            while ((row = br.readLine()) != null)
            {
                String splittedRow[] = row.split("\\|");
                if (splittedRow[0] != null && splittedRow[0].equals(comp)) 
                {
                    notMappedFields = splittedRow[1]; break; }
            }
        }
        stmt.execute(insert + "('"+comp+"','"+simple+"','"+cmplx_underscored+"','"
                +cmplx_pointed+"','"+cmplx_both+"','"+notMappedFields+"')");
    }

    static private Boolean isPresent(Statement stmt, String comp) throws SQLException
    { ResultSet res = stmt.executeQuery(present + getDefWhereStmt(comp)); return res.next(); }

}
